home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C / Applications / Python 1.3.3 / Python 133 68K / Lib / img / imgjpeg.py < prev    next >
Text File  |  1996-05-20  |  4KB  |  129 lines

  1. """A module that reads JPEG files using the SGI Compression Library.
  2.  
  3. This module should only be used in a python-interpreter with the cl
  4. module configured, otherwise the builtin imgjpeg module is better."""
  5.  
  6. import cl
  7. from imgformat import rgb, rgb_b2t, xrgb8, xrgb8_b2t, xgrey, xgrey_b2t, \
  8.               rgb8, rgb8_b2t, grey, grey_b2t
  9.  
  10. error = 'imgpjpeg.error'
  11.  
  12. class reader:
  13.     def __init__(self, filename):
  14.     self._filename = filename
  15.     self._file = f = open(filename, 'rb')
  16.     header = f.read(16)
  17.     scheme = cl.QueryScheme(header)
  18.     self._decompressor = decomp = cl.OpenDecompressor(scheme)
  19.     size = cl.QueryMaxHeaderSize(scheme)
  20.     if size > len(header):
  21.         header = header + f.read(size - len(header))
  22.     headersize = decomp.ReadHeader(header)
  23.     self.width = decomp.GetParam(cl.IMAGE_WIDTH)
  24.     self.height = decomp.GetParam(cl.IMAGE_HEIGHT)
  25.     self.format_choices = rgb, xrgb8, xrgb8_b2t, xgrey
  26.     if not hasattr(cl, 'JPEG_SOFTWARE'):
  27.         self.format_choices = self.format_choices + (rgb_b2t, xgrey_b2t)
  28.     self.format = rgb        # default format
  29.  
  30.     def args(self):
  31.     return self.__dict__
  32.     
  33.     def read(self):
  34.     if self.format in (rgb, rgb_b2t):
  35.         original_format = cl.RGBX
  36.     elif self.format in (xrgb8, xrgb8_b2t, rgb8, rgb8_b2t):
  37.         original_format = cl.RGB332
  38.     elif self.format in (xgrey, xgrey_b2t, grey, grey_b2t):
  39.         original_format = cl.GRAYSCALE
  40.     else:
  41.         raise error, 'Unknown format'
  42.     if self.format in (rgb_b2t, xrgb8_b2t, xgrey_b2t, rgb8_b2t, grey_b2t):
  43.         orientation = cl.BOTTOM_UP
  44.     else:
  45.         orientation = cl.TOP_DOWN
  46.     width = self.width
  47.     if original_format == cl.RGB332 and hasattr(cl, 'JPEG_SOFTWARE'):
  48.         # Irix 5.3 uses more buffer than it should, so allocate some extra
  49.         width = (width + 3) & ~3
  50.     bbp = cl.BytesPerPixel(original_format)
  51.     params = [cl.ORIGINAL_FORMAT, original_format,
  52.           cl.ORIENTATION, orientation,
  53.           cl.FRAME_BUFFER_SIZE, width * self.height * bbp]
  54.     self._decompressor.SetParams(params)
  55.     self._file.seek(0)
  56.     data = self._decompressor.Decompress(1, self._file.read())
  57.     if hasattr(cl, 'JPEG_SOFTWARE'):
  58.         if self.width & 1:
  59.         # Irix 5.3 has difficulty with odd-width images.  It
  60.         # rounds the width down to an even number, so we
  61.         # double the right-most pixel so that the image gets
  62.         # the original width again.
  63.         rv = ''
  64.         w = (self.width - 1) * bbp
  65.         for i in range(0, self.height * w, w):
  66.             rv = rv + data[i:i+w] + data[i+w-bbp:i+w]
  67.         return rv
  68.         # only return the image, not the extra space
  69.         return data[:self.width*self.height*bbp]
  70.     else:
  71.         return data
  72.  
  73.     def write(self, data):
  74.     raise error, 'Cannot write() to reader'
  75.  
  76. class writer:
  77.     def __init__(self, filename):
  78.     self._filename = filename
  79.     self.format_choices = rgb, rgb_b2t, xrgb8, xrgb8_b2t, xgrey, xgrey_b2t
  80.     self.format = rgb
  81.  
  82.     def args(self):
  83.     return self.__dict__
  84.     
  85.     def _get(self, attr):
  86.     try:
  87.         return getattr(self, attr)
  88.     except AttributeError:
  89.         raise error, "Required attribute '%s' missing"%attr
  90.  
  91.     def read(self):
  92.     raise error, 'Cannot read() from writer'
  93.  
  94.  
  95.     def write(self, data):
  96.     width = self._get('width')
  97.     height = self._get('height')
  98.     format = self._get('format')
  99.     if format in (rgb, rgb_b2t):
  100.         original_format = cl.RGBX
  101.     elif format in (xrgb8, xrgb8_b2t):
  102.         original_format = cl.RGB332
  103.     elif format in (xgrey, xgrey_b2t):
  104.         original_format = cl.GRAYSCALE
  105.     else:
  106.         raise error, 'Unknown format'
  107.     if format in (rgb_b2t, xrgb8_b2t, xgrey_b2t):
  108.         orientation = cl.BOTTOM_UP
  109.     else:
  110.         orientation = cl.TOP_DOWN
  111.     if width * height * cl.BytesPerPixel(original_format) != len(data):
  112.         raise error, 'Incorrect datasize'
  113.     params = [cl.ORIGINAL_FORMAT, original_format,
  114.           cl.ORIENTATION, orientation,
  115.           cl.IMAGE_WIDTH, width,
  116.           cl.IMAGE_HEIGHT, height]
  117.     try:
  118.         quality = self.quality
  119.     except AttributeError:
  120.         pass
  121.     else:
  122.         params.append(cl.QUALITY_FACTOR)
  123.         params.append(quality)
  124.     compressor = cl.OpenCompressor(cl.JPEG)
  125.     compressor.SetParams(params)
  126.     data = compressor.Compress(1, data)
  127.     file = open(self._filename, 'wb')
  128.     file.write(data)
  129.